package tester.main;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

import tester.parser.TesterConfig;
import tester.parser.TesterXMLParser;
import tester.test.Test;
import tester.test.builder.ElevatorBuilder;

import dispatcher.group.gui.network.GroupDispatcherGUIObserverThread;
import dispatcher.person.gui.network.PersonDispatcherGUIObserverThread;

/**
 * This is the main class that will handing parsing the xml and running the test
 * @author Caleb Chan
 *
 */
public class DispatcherTester {
	
	private GroupDispatcherGUIObserverThread groupTestThread;
	private PersonDispatcherGUIObserverThread personTestThread;
	
	private InetAddress address;
	private int port;
	
	private ArrayList<Test> testSuite;
	private TesterXMLParser parser;
	
	/**
	 * DispatcherTester constructor
	 * @param address The address of the person and group dispatcher
	 * @param port The port of the person and group dispatcher
	 */
	public DispatcherTester(InetAddress address, int port){
		try {
			this.address = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		this.port = port;
		this.testSuite = new ArrayList<Test>();
	}
	
	/**
	 * This method will initialize the group handler
	 */
	public void initializeGroupHandler(){
		if (address == null){
			return;
		}
		groupTestThread = new GroupDispatcherGUIObserverThread(address, TesterConfig.getInstance().getGdPort());
		groupTestThread.start();
	}
	
	/**
	 * This method will initialize the person handler
	 */
	public void initializePersonHandler(){
		if (address == null){
			return;
		}
		personTestThread = new PersonDispatcherGUIObserverThread(address, TesterConfig.getInstance().getPdPort());
		personTestThread.start();
	}
	
	/**
	 * This method will shutdown all the system handlers
	 */
	public void shutdownHandlers(){
		if (groupTestThread != null){
			groupTestThread.shutdownThread();
		}
		if (personTestThread != null){
			personTestThread.shutdownThread();
		}
	}
	
	/**
	 * This method will initialize the system
	 */
	public void initializeSystem(){
			
		// Create Initial Elevators
		for(int i = 0; i < TesterConfig.getInstance().getInitalElevators(); i++){
			String eFilePath = TesterConfig.getInstance().getElevatorPath();
			ElevatorBuilder.getInstance().buildElevator(eFilePath, "localhost", port);
		}
	}
	
	/**
	 * This method will destroy the elevators
	 */
	public void destroySystem(){		
		ElevatorBuilder.getInstance().destroyAllElevatorProcess();
	}
	
	/**
	 * This method will parse the XML file
	 * @param fileName The filename of the tester to parse
	 */
	public void parseFile(String fileName){
		parser = new TesterXMLParser(fileName);
		parser.parseFile();
		testSuite.addAll(parser.getTestSuite());
	}
	
	/**
	 * This method will run the test suite
	 */
	public void runTestSuite(){
		// Checks if the address is null
		if (address == null){
			return;
		}
		// Checks if there any test to run
		if(testSuite.size() < 1){
			return;
		}
		// This will run all the test in the suite
		for(Test t : testSuite){
			t.setReceiverHandler(groupTestThread);
			t.setSenderHandler(personTestThread);
			t.runTest();
			t.compileTest();
			System.out.println(t.printResults());
			System.out.println("Average Wait Time : " + (t.calculateWaitTimes()));
			System.out.println("Average Travel Time : " + (t.calculateTravelTime()));
			System.out.println("Average Overall Time : " + (t.calculateOverallTime()));
		}
	}
}
